﻿// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

#if SILVERLIGHT
extern alias Silverlight;
#endif

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Interactivity;
using Microsoft.Windows.Design;
using Microsoft.Windows.Design.Features;
using Microsoft.Windows.Design.Metadata;
using Expression.Samples.Interactivity;



[assembly: ProvideMetadata(typeof(Expression.Samples.Interactivity.Design.InteractivityMetadataStore))]

namespace Expression.Samples.Interactivity.Design {

	/// <summary>
	/// Provides design-time metadata for all of the classes.
	/// </summary>
	public class InteractivityMetadataStore : IProvideAttributeTable {
		#region IProvideAttributeTable Members

		public AttributeTable AttributeTable {
			get {
				AttributeTableBuilder attributeTableBuilder = new AttributeTableBuilder();

				// Data
				attributeTableBuilder.AddCustomAttributes(typeof(CallDataMethod), new ToolboxCategoryAttribute("Data"));
				attributeTableBuilder.AddCustomAttributes(typeof(CallDataMethod), new DefaultBindingPropertyAttribute("Target"));

				attributeTableBuilder.AddCustomAttributes(typeof(DataStateBehavior), new ToolboxCategoryAttribute("Data"));
				attributeTableBuilder.AddCustomAttributes(typeof(DataStateBehavior), "Value", new TypeConverterAttribute(typeof(DumbTypeConverter)));
				attributeTableBuilder.AddCustomAttributes(typeof(DataStateBehavior), "FalseState", new CustomPropertyValueEditorAttribute(CustomPropertyValueEditor.StateName));
				attributeTableBuilder.AddCustomAttributes(typeof(DataStateBehavior), "TrueState", new CustomPropertyValueEditorAttribute(CustomPropertyValueEditor.StateName));
				attributeTableBuilder.AddCustomAttributes(typeof(DataStateBehavior), new DefaultBindingPropertyAttribute("Binding"));

				attributeTableBuilder.AddCustomAttributes(typeof(DataStateSwitchBehavior), new ToolboxCategoryAttribute("Data"));
				attributeTableBuilder.AddCustomAttributes(typeof(DataStateSwitchCase), "Value", new TypeConverterAttribute(typeof(DumbTypeConverter)));
				attributeTableBuilder.AddCustomAttributes(typeof(DataStateSwitchBehavior), new DefaultBindingPropertyAttribute("Binding"));

				attributeTableBuilder.AddCustomAttributes(typeof(DataTrigger), "Value", new TypeConverterAttribute(typeof(DumbTypeConverter)));
				attributeTableBuilder.AddCustomAttributes(typeof(DataTrigger), new DefaultBindingPropertyAttribute("Binding"));

				attributeTableBuilder.AddCustomAttributes(typeof(FluidBindProperty), new ToolboxCategoryAttribute("Data"));
				attributeTableBuilder.AddCustomAttributes(typeof(FluidBindProperty), new DefaultBindingPropertyAttribute("Binding"));

				attributeTableBuilder.AddCustomAttributes(typeof(InvokeDataCommand), new ToolboxCategoryAttribute("Data"));
				attributeTableBuilder.AddCustomAttributes(typeof(InvokeDataCommand), new DefaultBindingPropertyAttribute("Command"));

				attributeTableBuilder.AddCustomAttributes(typeof(SetDataProperty), "Value", new TypeConverterAttribute(typeof(DumbTypeConverter)));
				attributeTableBuilder.AddCustomAttributes(typeof(SetDataProperty), new ToolboxCategoryAttribute("Data"));
				attributeTableBuilder.AddCustomAttributes(typeof(SetDataProperty), new DefaultBindingPropertyAttribute("Binding"));
				attributeTableBuilder.AddCustomAttributes(typeof(SetDataProperty), "Binding", new BindableAttribute(BindableSupport.Yes, BindingDirection.TwoWay));
				
				//Experimental
				attributeTableBuilder.AddCustomAttributes(typeof(CallMethod), new ToolboxCategoryAttribute("Experimental"));
				attributeTableBuilder.AddCustomAttributes(typeof(ClippingBehavior), new ToolboxCategoryAttribute("Experimental"));

				attributeTableBuilder.AddCustomAttributes(typeof(GoToNextState), new ToolboxCategoryAttribute("Experimental"));

				attributeTableBuilder.AddCustomAttributes(typeof(GoToPreviousState), new ToolboxCategoryAttribute("Experimental"));

				attributeTableBuilder.AddCustomAttributes(typeof(SetProperty), new ToolboxCategoryAttribute("Experimental"));
				attributeTableBuilder.AddCustomAttributes(typeof(SetProperty), "Value", new TypeConverterAttribute(typeof(DumbTypeConverter)));

				attributeTableBuilder.AddCustomAttributes(typeof(ShowMessageBox), new ToolboxCategoryAttribute("Experimental"));

				attributeTableBuilder.AddCustomAttributes(typeof(StateChanged), "StateName", new CustomPropertyValueEditorAttribute(CustomPropertyValueEditor.StateName));

				//Media
				attributeTableBuilder.AddCustomAttributes(typeof(PlayMedia), new ToolboxCategoryAttribute("Media"));
				attributeTableBuilder.AddCustomAttributes(typeof(PauseMedia), new ToolboxCategoryAttribute("Media"));
#if SILVERLIGHT_DESIGN
				attributeTableBuilder.AddCustomAttributes(typeof(TogglePlayPauseMedia), new ToolboxCategoryAttribute("Media"));
#endif
				attributeTableBuilder.AddCustomAttributes(typeof(RewindMedia), new ToolboxCategoryAttribute("Media"));
				attributeTableBuilder.AddCustomAttributes(typeof(StopMedia), new ToolboxCategoryAttribute("Media"));

				//Prototyping
				attributeTableBuilder.AddCustomAttributes(typeof(ListBoxAddOne), new ToolboxCategoryAttribute("Prototyping"));
				attributeTableBuilder.AddCustomAttributes(typeof(ListBoxRemoveOne), new ToolboxCategoryAttribute("Prototyping"));
				attributeTableBuilder.AddCustomAttributes(typeof(ListBoxRemoveThisItem), new ToolboxCategoryAttribute("Prototyping"));


				attributeTableBuilder.AddCustomAttributes(typeof(TargetedTriggerBase), "SourceName", new CustomPropertyValueEditorAttribute(CustomPropertyValueEditor.Element));

				// Adds the custom ink editor for the GesturePointList to edit the MouseGestureTrigger.
				attributeTableBuilder.AddCustomAttributes(typeof(MouseGestureTrigger), "GesturePointList", new EditorAttribute(typeof(GesturePointListEditor), typeof(GesturePointListEditor)));

				foreach (Type type in typeof(DataTrigger).Assembly.GetTypes()) {
					if (typeof(Behavior).IsAssignableFrom(type) ||
						typeof(TriggerAction).IsAssignableFrom(type) ||
						typeof(TriggerBase).IsAssignableFrom(type))

						foreach(PropertyInfo property in type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public))
							attributeTableBuilder.AddCustomAttributes(type, property.Name, new CategoryAttribute("Common Properties"));
				}
				
				DescriptionLoader.LoadComments(typeof(MouseGestureTrigger).Assembly, attributeTableBuilder, "Expression.Samples.Interactivity.xml");

				return attributeTableBuilder.CreateTable();
			}
		}

		/// <summary>
		/// Gives properties of type Object a string entry field in Blend's property editor.
		/// </summary>
		private class DumbTypeConverter : TypeConverter {
			public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
				return true;
			}

			public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
				return destinationType == typeof(object);
			}

			public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
				return value;
			}

			public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
				return value;
			}
		}

		#endregion
	}
}
